Perl 6 - stackoverflow(2017.1.1)

我想匹配任意一组单词,但是失败了,请问怎样才能正确地匹配到?

my @a=<a b c d e f>;
my $x="a1234567";
say $x ~~ m/ @a.any /;

Answer

my @a = <a b c d e f>;
my $x = "a1234567";
say $x ~~ /@a/

/@a//| @a/ 相同,它是最长的备选分支。对于备选分支,你可以使用 /|| @a/

sub foo($x) {
  $x**2
}

my $alist = (1,2, &foo ... ^ * > 100);

我想得到 (1 4 9 16 25 .. ) 而程序得到的是 (1 2 4 16 256)

Answer:

my @a = (1..*).map(* ** 2);  # using a Whatever-expression
my @a = (1..*).map(&foo);    # using your `foo` function

或者使用 Haskell/Python 那样的列表解析式:

my @a = ($_ ** 2 for 1..*);  # using an in-line expression
my @a = (foo $_ for 1..*);   # using your `foo` function

另外还有一种方法:

my @alist = {(++$)²} ... * > 70; # stop immediately after past 70
say @alist; # [1 4 9 16 25 36 49 64 81]

my @alist = {(++$)²} ...^ * > 70; # stop immediately before past 70
say @alist; # [1 4 9 16 25 36 49 64]

个人不推荐使用 $ 匿名变量的这种写法, 对于 new comer 不太友好。

Is it possible to use junction to match any of the values in a junction? I want to match any of the values in an array. What is the proper way to do it?

> my @a=<a b c>
[a b c]
> any(@a)
any(a, b, c)
> my $x=any(@a)
any(a, b, c)
> my $y = "a 1"
a 1
> say $y ~~ m/ $x /
False
> say $y ~~ m/ "$x" /
False
> my $x = any(@a).Str
any("a", "b", "c")
> say $y ~~ m/ $x /
False
> say $y ~~ m/ || $x /
False
> say $y ~~ m/ || @a /
「a」

Answer

junctions 不该被插值到正则表达式中。它们应该被用在普通的 Perl 6 表达式中,特别是带有比较操作符的表达式(例如 eq):

my @a = <x y z>;
say    "y" eq any(@a);  # any(False, True, False)
say so "y" eq any(@a);  # True

要在正则表达式中匹配一个数组的任意值,就在正则表达式中写上那个数组名好了(以@开头)。默认地,这被插值为 | 备选分支(“longest match”),但是你也可以把他指定为 || 备选分支(“first match”)。

my @a = <foo bar barkeep>;
say "barkeeper" ~~ / @a /;     # 「barkeep」
say "barkeeper" ~~ / || @a /;  # 「bar」

我需要排序数组的数组, .sort 方法能不能按照内层数组的不同索引来排序呢?

要排序的数组在一个更大的数组的外面:(birthday 是 'mmddyy' 格式的:)

my @allRecords = [ [birthday1 firstName1 lastName1 [data1]
                   [birthday2 firstName2 lastName2 [data2] 
                   ...
                   [birthdayN firstNameN lastNameN [dataN] ];

@allRecords.sort by itself sorts by birthdays.

有什么好方法能按照 firstName 或 lastName 或 按照内层数组里面的数据来排序?

Answer

sort 方法接受一个可选的 sub 参数。如果元数是 1, 那么它使用返回值作为比较操作数;如果元数为 2, 那么你可以在两个元素之间手动作比较,两个元素的比较会返回 Less, Same, More

拿你上面的例子来说,我们可以像这样按照 first name 进行排序:

@allRecords.sort(*.[1])

我们可以先按照 last name 再按照 first name 进行排序,然后按照 birthday 来做单独的比较,就像这样:

@allRecords.sort(-> $a,$b {
    $a[2] cmp $b[2] || $a[1] cmp $b[1] || $a[0] cmp $b[0]
});

或者再次通过转换操作数:

@allRecords.sort(*.[2...0]);

变换 birthday 条目以至于我们能先按照 year 排序作为练习留给读者完成,但是其中一种方法是在合适的地方添加像这样的代码:

.comb(2).list.rotate(-1).join

你可以按照 lastname,firstname, birthday 这样的顺序排序:

@a.sort: *[2...0]

还有两个问题:

  • *.[1]*[1] 有什么区别?

两者没有任何区别,但是前者可读性更好!

  • range 操作符和 ... 序列操作符有什么区别

range 不能倒数, ... 可以倒数。

在 Perl 6 中怎样找出列表中最大值的索引?

Answer

my @list = 1,2,9,6,9,5;
@list.maxpairs; # [2 => 9 4 => 9]

@list.maxpairs 用于获取索引和对应最大值的所有对儿。
@list.pairs.max(*.value).key 用于仅获取单个索引。

> @list.pairs.max(*.value).key
2

如何彻底地展平 Perl 6 的列表?这个问题不同于 How do I “flatten” a list of lists in perl 6?, 后者不是彻底的 flat。

my @a  = 'a', ('b', 'c' );
my @b  = ('d',), 'e', 'f', @a;
my @c  = 'x', $( 'y', 'z' ), 'w';

my @ab = @a, @b, @c;
say "ab: ", @ab;

my @f = @ab;

@f = gather {
    while @f {
        @f[0].elems == 1 ??
            take @f.shift.Slip
                !!
            @f.unshift( @f.shift.Slip )
        }
    }

say "f: ", @f;

这打印出:

ab: [[a (b c)] [(d) e f [a (b c)]] [x (y z) w]]
f: [a b c d e f a b c x y z w]

但这不够简洁。一种可行的办法是使用:gather/take/deepmap:

say gather @ab.deepmap(*.take)

postcircumfix [] 操作符可用于多维下标来获取一组展平的叶子节点,直到特定的深度,尽管 “无限深度” 版本还没有实现:

say @ab[*;*];     # (a (b c) (d) e f [a (b c)] x (y z) w)
say @ab[*;*;*];   # (a b c d e f a (b c) x y z w)
say @ab[*;*;*;*]; # (a b c d e f a b c x y z w)
say @ab[**];      # HyperWhatever in array index not yet implemented. Sorry.
  • 避免容器化 (containerization)

内置的 flat 函数能很好地展平深度嵌套的列表。问题是它不能落进 item 容器(Scalar)中。嵌套列表中非故意的 item 容器的常见来源有:

  • 数组(但不是列表)将其每个元素包装在一个新的 item 容器中,无论它之前有没有。
  • 如何避免:如果不需要 Array 提供的可变性,请使用列表的列表而不是数组的数组。使用绑定 := 可以用来代替赋值,将列表存储在@变量中,而不将其转换为数组
my @a  := 'a', ('b', 'c' );
my @b  := ('d',), 'e', 'f', @a;

say flat @b;  # (d e f a b c)
  • $variables 是 item 容器。
  • 如何避免:当将列表存储在 $ 变量中,然后将其作为元素插入到另一个列表中时,使用 <> 来对它进行 decontainerize(解容器化)。当把 $ 变量传递给 flat 时, 父列表的容器也可以使用 | 绕过:
my $a = (3, 4, 5);
my $b = (1, 2, $a<>, 6);

say flat |$b;  # (1 2 3 4 5 6)

未完待续。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容